﻿/************************************************************************

   Extended Silverlight Toolkit

   Copyright (C) 2010-2012 Xceed Software Inc.

   This program is provided to you under the terms of the Microsoft Public
   License (Ms-PL) as published at http://extendedsilverlight.codeplex.com/license

   Please purchase a commercial version of this toolkit if you are using
   it in a commercial product. The commercial versions support the project,
   and also include more features for each control, priority support,
   source code, updates, removed watermark, and a proprietary license.

   Visit http://xceed.com and follow @datagrid on Twitter.

  **********************************************************************/

using System;
using System.Windows;

// This source code obtained from CodeProject and 
// the URL is http://www.codeproject.com/KB/silverlight/TextOnAPathSilverlight.aspx?msg=2872095.
namespace Xceed.Silverlight.Utils
{
  internal struct Vector
  {
    public Vector( double x, double y )
    {
      m_point = new Point( x, y );
    }

    public double Length
    {
      get
      {
        return ( Math.Sqrt( Math.Pow( m_point.X, 2.0 ) + Math.Pow( m_point.Y, 2.0 ) ) );
      }
    }

    public void Normalize()
    {
      if(this.Length == 0 )
        throw new System.InvalidOperationException( "Vector Length is zero, can not normalize" );

      double l = this.Length;
      m_point.X /= l;
      m_point.Y /= l;
    }

    public double X
    {
      get
      {
        return m_point.X;
      }
      set
      {
        m_point.X = value;
      }
    }

    public double Y
    {
      get
      {
        return m_point.Y;
      }
      set
      {
        m_point.Y = value;
      }
    }

    //
    // Summary:
    //     Subtracts one specified vector from another.
    //
    // Parameters:
    //   vector1:
    //     The vector from which vector2 is subtracted.
    //
    //   vector2:
    //     The vector to subtract from vector1.
    //
    // Returns:
    //     The difference between vector1 and vector2.
    public static Vector operator -( Vector vector1, Vector vector2 )
    {
      return new Vector( vector1.X - vector2.X, vector1.Y - vector2.Y );
    }


    public static Vector operator -( Vector vector )
    {
      return new Vector( -vector.X, -vector.Y );
    }

    //
    // Summary:
    //     Multiplies the specified scalar by the specified vector and returns the resulting
    //     vector.
    //
    // Parameters:
    //   scalar:
    //     The scalar to multiply.
    //
    //   vector:
    //     The vector to multiply.
    //
    // Returns:
    //     The result of multiplying scalar and vector.
    public static Vector operator *( double scalar, Vector vector )
    {
      return new Vector( vector.X * scalar, vector.Y * scalar );
    }

    //
    // Summary:
    //     Multiplies the specified vector by the specified scalar and returns the resulting
    //     vector.
    //
    // Parameters:
    //   vector:
    //     The vector to multiply.
    //
    //   scalar:
    //     The scalar to multiply.
    //
    // Returns:
    //     The result of multiplying vector and scalar.
    public static Vector operator *( Vector vector, double scalar )
    {
      return new Vector( vector.X * scalar, vector.Y * scalar );
    }

    //
    // Summary:
    //     Transforms the coordinate space of the specified vector using the specified
    //     System.Windows.Media.Matrix.
    //
    // Parameters:
    //   vector:
    //     The vector to transform.
    //
    //   matrix:
    //     The transformation to apply to vector.
    //
    // Returns:
    //     The result of transforming vector by matrix.
    //public static Vector operator *(Vector vector, Matrix matrix)
    //{
    //    Vector result = new Vector();
    //    result.X = (matrix.M11*vector.X) + (matrix.M12*vector.Y);
    //    result.Y = (matrix.M21*vector.X) + (matrix.M22*vector.Y);
    //    return result;
    //}

    //
    // Summary:
    //     Calculates the dot product of the two specified vector structures and returns
    //     the result as a System.Double.
    //
    // Parameters:
    //   vector1:
    //     The first vector to multiply.
    //
    //   vector2:
    //     The second vector to multiply.
    //
    // Returns:
    //     Returns a System.Double containing the scalar dot product of vector1 and
    //     vector2, which is calculated using the following formula:vector1.X * vector2.X
    //     + vector1.Y * vector2.Y
    public static double operator *( Vector vector1, Vector vector2 )
    {
      return ( vector1.X * vector2.X ) + ( vector1.Y * vector2.Y );
    }

    //
    // Summary:
    //     Adds two vectors and returns the result as a vector.
    //
    // Parameters:
    //   vector1:
    //     The first vector to add.
    //
    //   vector2:
    //     The second vector to add.
    //
    // Returns:
    //     The sum of vector1 and vector2.
    public static Vector operator +( Vector vector1, Vector vector2 )
    {
      return ( new Vector( vector2.X + vector1.X, vector2.Y + vector1.Y ) );
    }

    //
    // Summary:
    //     Translates a point by the specified vector and returns the resulting point.
    //
    // Parameters:
    //   vector:
    //     The vector used to translate point.
    //
    //   point:
    //     The point to translate.
    //
    // Returns:
    //     The result of translating point by vector.
    public static Point operator +( Point point, Vector vector )
    {
      return new Point( point.X + vector.X, point.Y + vector.Y );
    }

    Point m_point;
  }
}
